home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / plugin / walk / person.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-03  |  13.8 KB  |  670 lines

  1. #include "walk.h"
  2.  
  3. void person::init()
  4. {
  5.     if (bp==0)
  6.         bp=(birth_pad *)flyengine->get_next_active_object(0,TYPE_BIRTH_PAD);
  7.     if (bp==0)
  8.         {
  9.         if (flyengine->get_random_point(pos,height)==0)
  10.             pos.null();
  11.         }
  12.     else
  13.         {
  14.         pos=bp->pos;
  15.         bp->animtime0=flyengine->cur_time;
  16.         }
  17.     pos.z+=height;
  18.  
  19.     align_z(vector(1,0,0));
  20.     ls=*((local_system *)this);
  21.     updownrot=0;
  22.     
  23.     vel.null();
  24.     force.null();
  25.     
  26.     contactobj=0;
  27.     jumpflag=0;
  28.     curshield=shield;
  29.  
  30.     zoompos=0;
  31.     flyengine->camangle=zoomangle1;
  32. }
  33.  
  34. mesh *person::ray_intersect(vector& ro,vector& rd,vector& ip,float& dist,int &facenum,float rad)
  35.     if (p_anim[cur_anim]) 
  36.     {
  37.         static float d1,d2;
  38.         vector ro_local=ro-pos;
  39.         vector rd_local=rd*mat_t;
  40.         ro_local.z+=height/2;
  41.         ro_local=ro_local*mat_t;
  42.         if (p_anim[cur_anim]->bbox.ray_intersect(ro_local,rd_local,d1,d2))
  43.         {
  44.         facenum=p_anim[cur_anim]->ray_intersect(ro_local,rd_local,ip,dist,rad);
  45.         if (facenum>-1)
  46.             {
  47.             ip=ip*mat+pos;
  48.             ip.z-=height/2;
  49.             bsp_object *so=flyengine->stepobj;
  50.             
  51.             if (directx && directx->mpmode==FLYMP_SERVER)
  52.             if (flyengine->stepobj)
  53.             if (flyengine->stepobj->type==TYPE_LASER || flyengine->stepobj->type==TYPE_MISSILE)
  54.             if (dist<1.0f)
  55.                 {
  56.                 int from=((gun_projectile *)flyengine->stepobj)->player;
  57.                 float value=((gun_projectile *)(flyengine->stepobj))->damage;
  58.                 curshield-=value;
  59.                 if (directx->mpmode==FLYMP_SERVER)
  60.                     mp_send_damage(from,ip,value);
  61.                 else flyengine->filter.x=1.0f;
  62.                 if (curshield<=0)
  63.                     die(((gun_projectile *)flyengine->stepobj)->player,ip,-1);
  64.                 }
  65.  
  66.             return p_anim[cur_anim];
  67.             }
  68.         }
  69.     }
  70.     return 0;
  71. }
  72.  
  73. void person::mp_send_pos(int msgtype,int msgflag)
  74. {
  75.     static struct mp_data data;
  76.     
  77.     data.type=msgtype;
  78.     data.dpid=directx->players[player].dpid;
  79.     data.flag=msgflag;
  80.     data.pos=pos;
  81.     data.vel=vel;
  82.     data.walkvel=walkvec;
  83.     data.X=ls.X;
  84.     data.Y=ls.Y;
  85.     data.Z=ls.Z;
  86.     data.rot=updownrot;
  87.  
  88.     directx->send_message((mp_msg *)&data,sizeof(struct mp_data));
  89. }
  90.  
  91. void person::mp_send_damage(int from,vector& pushvec,float value)
  92. {
  93.     static struct mp_data_damage data;
  94.     
  95.     data.type=FLYMP_MSG_DAMAGE;
  96.     data.dpid=directx->players[player].dpid;
  97.     data.from=from;
  98.     data.pushvec=pushvec;
  99.     data.value=value;
  100.  
  101.     directx->send_message((mp_msg *)&data,sizeof(struct mp_data_damage));
  102. }
  103.  
  104. void person::die(int killer,vector& hitpos,int padindx)
  105. {
  106.     int i;
  107.     if (node && gb)
  108.     for( i=0;i<ngib;i++ )
  109.         {
  110.         gib *x=(gib *)gb->clone();
  111.         x->pos=pos;
  112.         x->pos.x+=FRAND*radius;
  113.         x->pos.y+=FRAND*radius;
  114.         x->pos.z+=FRAND*radius;
  115.         x->vel=x->pos-hitpos;
  116.         x->vel.normalize();
  117.         x->vel*=gibforce;
  118.         flyengine->activate(x);
  119.         }
  120.  
  121.     int npad=0;
  122.     birth_pad *pad=0,*pads[16];
  123.     while( pad=(birth_pad *)flyengine->get_next_active_object(pad,TYPE_BIRTH_PAD))
  124.         pads[npad++]=pad;
  125.     if (padindx==-1&&npad)
  126.         padindx=rand()%npad;
  127.     else if (padindx>=npad)
  128.             padindx=-1;
  129.     if (padindx==-1)
  130.         bp=0;
  131.     else bp=pads[padindx];
  132.  
  133.     if (player==killer)
  134.         if (killer==0)
  135.             {
  136.             flyengine->set_status_msg("YOU COMMITTED SUICIDE",directx->players[killer].name);
  137.             ((person *)flyengine->player)->points--;
  138.             }
  139.         else
  140.             flyengine->set_status_msg("%s COMMITTED SUICIDE",directx->players[killer].name);
  141.     else
  142.         if (killer==0)
  143.             {
  144.             ((person *)flyengine->player)->points++;
  145.             flyengine->set_status_msg("YOU KILLED %s",directx->players[player].name);
  146.             }
  147.         else 
  148.         if (player==0)
  149.             flyengine->set_status_msg("%s KILLED YOU",directx->players[killer].name);
  150.         else 
  151.             flyengine->set_status_msg("%s KILLED %s",directx->players[killer].name,directx->players[player].name);
  152.  
  153.     if (directx->mpmode==FLYMP_SERVER)
  154.         mp_send_kill(killer,padindx,hitpos);
  155.  
  156.     init();
  157.     add_to_bsp();
  158. }
  159.  
  160. void person::mp_send_kill(int killer,int pad,vector& hitpoint)
  161. {
  162.     static struct mp_data_kill data;
  163.     
  164.     data.type=FLYMP_MSG_KILL;
  165.     data.dpid=directx->players[player].dpid;
  166.     data.dpidpoints=directx->players[killer].dpid;
  167.     data.pos=pos;
  168.     data.hitpos=hitpoint;
  169.     data.birthpad=pad;
  170.  
  171.     directx->send_message((mp_msg *)&data,sizeof(struct mp_data_kill));
  172. }
  173.  
  174. int person::step(int dt)    
  175. {
  176.     if (directx->mpmode==FLYMP_SERVER && player==0)
  177.         {
  178.         life=-1;
  179.         flyengine->cam=source;
  180.         flyengine->player=source;
  181.         directx->players[0].data=0;
  182.         return 0;
  183.         }
  184.  
  185.     vector p,v,ip,rd;
  186.     float dist;
  187.     mesh *lastcontact=contactobj;
  188.  
  189.     // if outside level, wrong place
  190.     if (node==0)
  191.     {
  192.         if (player==0)
  193.             die(0,vector(0,0,0),-1);
  194.         return 1;
  195.     }
  196.  
  197.     // if spoton, illum
  198.     if (spot && (flag&0x100))
  199.         spot->reposition(this);
  200.  
  201.     // check keys/mouse with horizontal look dir
  202.     if (player==0)
  203.         do_input(dt);
  204.  
  205.     // add jump forces 
  206.     if (jumpflag!=0)
  207.     {
  208.     jumpflag-=dt;
  209.     if (jumpflag<=0)
  210.         {
  211.         force+=jumpvec*((float)(dt+jumpflag)/dt);
  212.         jumpflag=0;
  213.         }
  214.     else force+=jumpvec;
  215.     }
  216.  
  217.     // exclude the player model from any collision
  218.     flyengine->excludecollision=this;
  219.  
  220.     // apply forces and compute collision
  221.  
  222.     v=vel+force*((float)dt/mass);
  223.     p=pos+(walkvec+vel)*(float)dt;
  224.     compute_collision(p,v);
  225.     pos=p;
  226.     vel=v;
  227.     force.null();
  228.  
  229.     contactobj=0;
  230.     p.z-=height;
  231.     rd=p-pos;
  232.  
  233.     bsp_object *o=0;
  234.     while( o=flyengine->get_next_active_object(o,TYPE_JUMP_PAD) )
  235.         if (contactobj=o->ray_intersect(pos,rd,ip,dist,contactfacenum))
  236.             if (dist<=1.0f && jumpflag==0)
  237.                 {
  238.                 jumpvec=
  239.                     contactobj->faces[contactfacenum]->normal*
  240.                     ((jump_pad *)o)->jumpforce;
  241.                 if (((jump_pad *)o)->invert)
  242.                     {
  243.                     jumpvec.x=-jumpvec.x;
  244.                     jumpvec.y=-jumpvec.y;
  245.                     }
  246.                 jumpflag=((jump_pad *)o)->forcetime;
  247.                 break;
  248.                 }
  249.             else contactobj=0;
  250.  
  251.     if (flyengine->collision_bsp(flyengine->bsp,pos,p))
  252.         {
  253.         contactobj=flyengine->hitmesh;
  254.         ip=flyengine->hitip;
  255.         contactfacenum=flyengine->hitface;
  256.         } 
  257.     else contactobj=0;
  258.  
  259.     // restore player model collision
  260.     flyengine->excludecollision=0;
  261.  
  262.     // if a network player, return
  263.     if (player!=0) 
  264.         return 1;
  265.  
  266.     // if in contact
  267.     if (contactobj)
  268.         {
  269.         if (lastcontact==0)
  270.             vel.null();
  271.         pos=ip;
  272.         pos.z+=height-0.1f;
  273.         }
  274.     else 
  275.         force.z-=gravity;
  276.  
  277.     directx->set_listener(
  278.         &pos.x,0,
  279.         &ls.Y.x,&ls.Z.x);
  280.  
  281.     return 1;
  282. }
  283.  
  284. void person::do_input(int dt)
  285. {
  286.     *((local_system *)this)=ls;
  287.  
  288.     static int lastmouse[2][2]={ { 0,0 },{ 0,0 } },lm=0,jumpkeyflag=0;
  289.     float mousedx=(directx->dims.lX+lastmouse[0][0]+lastmouse[1][0])/3.0f;
  290.     float mousedy=(directx->dims.lY+lastmouse[0][1]+lastmouse[1][1])/3.0f;
  291.     lastmouse[lm][0]=directx->dims.lX;
  292.     lastmouse[lm][1]=directx->dims.lY;
  293.     lm=!lm;
  294.  
  295.     unsigned char *diks=directx->diks;
  296.  
  297.     if (diks[0x39]&0x80) // SPACE key
  298.         if (jumpkeyflag==0)
  299.         {
  300.         jumpkeyflag=1;
  301.         if ( jumpflag==0 && contactobj)
  302.             {
  303.             jumpvec.null();
  304.             jumpvec.z+=jumpforce;
  305.             jumpflag=jumpforcetime;
  306.             }
  307.         }
  308.         else ;
  309.     else jumpkeyflag=0;
  310.  
  311.     walkvec.null();
  312.     if (diks[0x38]&0x80)    // ALT key
  313.         {
  314.         if (diks[0xcb]&0x80)    // left arrow
  315.             walkvec-=X*walkvel;
  316.  
  317.         if (diks[0xcd]&0x80)    // right arrow
  318.             walkvec+=X*walkvel;
  319.  
  320.         if (diks[0x1f]&0x80||    // S key
  321.             diks[0xc8]&0x80)    // up arrow
  322.             walkvec-=Z*walkvel;
  323.  
  324.         if (diks[0x2d]&0x80||    // X key
  325.             diks[0xd0]&0x80)    // down arrow
  326.             walkvec+=Z*walkvel;
  327.         }
  328.     else
  329.         {
  330.         if (diks[0xc8]&0x80)    // up arrow
  331.             {
  332.             updownrot-=dt*rotvel;
  333.             if (updownrot<-80) updownrot=-80;
  334.             }
  335.         
  336.         if (diks[0xd0]&0x80)    // down arrow
  337.             {
  338.             updownrot+=dt*rotvel;
  339.             if (updownrot>80) updownrot=80;
  340.             }
  341.  
  342.         if (diks[0xcb]&0x80)    // left arrow
  343.             rotate(dt*rotvel,Y);
  344.  
  345.         if (diks[0xcd]&0x80)    // right arrow
  346.             rotate(-dt*rotvel,Y);
  347.  
  348.         if (diks[0x10]&0x80)    // Q key
  349.             walkvec-=X*walkvel;
  350.  
  351.         if (diks[0x12]&0x80)    // E key
  352.             walkvec+=X*walkvel;
  353.  
  354.         if (diks[0x1f]&0x80)    // S key
  355.             walkvec-=Z*walkvel;
  356.  
  357.         if (diks[0x2d]&0x80)    // X key
  358.             walkvec+=Z*walkvel;
  359.         }
  360.  
  361.     if (diks[0x11]&0x80)   // W key
  362.         if ((flag&0x1000)==0)
  363.             flag^=0x1100;
  364.         else ;
  365.     else if (flag&0x1000)
  366.             flag^=0x1000;
  367.  
  368.     if (mousedx)    // mouse X
  369.         rotate(-mousedx*mousespeed,Y);
  370.  
  371.     if (mousedy)    // mouse Y
  372.         {
  373.         updownrot+=mousedy*mousespeed;
  374.         if (updownrot<-80) updownrot=-80;
  375.         if (updownrot>80) updownrot=80;
  376.         }
  377.  
  378.     ls=*((local_system *)this);
  379.     rotate(updownrot,X);
  380.  
  381.     if (g)
  382.     if (directx->diks[0x9d]&0x80 ||
  383.         directx->dims.rgbButtons[0]&0x80)
  384.         if (g->fire_status())
  385.             if (directx->mpmode==FLYMP_NOMP)
  386.             {
  387.                 g->fire(this,player);
  388.                 cur_anim_time=flyengine->cur_time;
  389.                 cur_anim=2;
  390.                 loop_anim=0;
  391.             }
  392.             else mp_send_pos(FLYMP_MSG_POS,flag|(points<<16));
  393.  
  394.     if (directx->dims.rgbButtons[1]&0x80)
  395.         {
  396.         zoompos+=dt;
  397.         if (zoompos>zoomtime) 
  398.             zoompos=zoomtime;
  399.         }
  400.     else
  401.         {
  402.         zoompos-=dt;
  403.         if (zoompos<0) 
  404.             zoompos=0;
  405.         }
  406.     flyengine->camangle=zoomangle1+(zoomangle2-zoomangle1)*((float)zoompos/zoomtime);
  407. }
  408.  
  409. void person::draw()
  410. {
  411.     if (player==0) return;
  412.  
  413.     if ((cur_anim&0xfe)==0)
  414.         if (vel.x!=0.0f || vel.y!=0.0f || vel.z!=0.0f ||
  415.             walkvec.x!=0.0f || walkvec.y!=0.0f || walkvec.z!=0.0f)
  416.             cur_anim=1;
  417.         else 
  418.             cur_anim=0;
  419.  
  420.     if (p_anim[cur_anim]==0 || w_anim[cur_anim]==0) 
  421.         return;
  422.  
  423.     int anim_time=p_anim[cur_anim]->nframes*100;
  424.     int ikey=flyengine->cur_time-cur_anim_time;
  425.     if (loop_anim==0)
  426.         if (ikey>=anim_time)
  427.             ikey=anim_time;
  428.     float fkey=(ikey%anim_time)/(float)anim_time;
  429.     p_anim[cur_anim]->set_key(fkey);
  430.     w_anim[cur_anim]->set_key(fkey);
  431.     p_anim[cur_anim]->texpic=skin;
  432.  
  433.     if(personshadow && flyengine->stencil==0)
  434.         {
  435.         personshadow->reposition(this);
  436.         personshadow->draw();
  437.         }
  438.  
  439.     if (flyengine->hwlights)
  440.         {
  441.         p_anim[cur_anim]->color.vec(1,1,1,1);
  442.         w_anim[cur_anim]->color.vec(1,1,1,1);
  443.         dynlights.init_draw(this);
  444.         }
  445.     else if (node)
  446.         {
  447.         p_anim[cur_anim]->color=node->color+dynlight;
  448.         w_anim[cur_anim]->color=node->color+dynlight;
  449.         dynlight.null();
  450.         }
  451.     glPushMatrix();
  452.     glTranslatef(pos.x,pos.y,pos.z-height/2);
  453.     glMultMatrixf((float *)&ls.mat);
  454.     p_anim[cur_anim]->draw();
  455.     w_anim[cur_anim]->draw();
  456.     if (flyengine->stencil)
  457.     {
  458.         glDisable(GL_LIGHTING);
  459.         int i,mini=-1;
  460.         float f,minf=BIG;
  461.         vector lp;
  462.         for( i=0;i<dynlights.nlights;i++ )
  463.         {
  464.             f=(dynlights.pos[i]-pos).length();
  465.             if (f<minf)
  466.             {
  467.                 minf=f;
  468.                 mini=i;
  469.             }
  470.         }
  471.         if (mini!=-1)
  472.         {
  473.             lp=dynlights.pos[mini]-pos;
  474.             lp.z+=height/2;
  475.             lp=lp*mat_t;
  476.             lp.normalize();
  477.             lp*=flyengine->shadowdepth;
  478.             p_anim[cur_anim]->draw_shadow_volume(lp);
  479.             w_anim[cur_anim]->draw_shadow_volume(lp);
  480.         }
  481.     }
  482.     glPopMatrix();
  483.  
  484.     if (flyengine->hwlights)
  485.         dynlights.end_draw();
  486.  
  487.     if (loop_anim==0 && ikey==anim_time)
  488.     {
  489.         cur_anim=0;
  490.         loop_anim=1;
  491.     }
  492. }
  493.  
  494. int person::get_custom_param_desc(int i,param_desc *pd)
  495. {
  496.     if (pd!=0)
  497.     switch(i)
  498.     {
  499.         case 0:
  500.             pd->type='f';
  501.             pd->data=&height;
  502.             strcpy(pd->name,"height");
  503.             break;
  504.         case 1:
  505.             pd->type='f';
  506.             pd->data=&jumpforce;
  507.             strcpy(pd->name,"jumpforce");
  508.             break;
  509.         case 2:
  510.             pd->type='i';
  511.             pd->data=&jumpforcetime;
  512.             strcpy(pd->name,"jumpforcetime");
  513.             break;
  514.         case 3:
  515.             pd->type='f';
  516.             pd->data=&gravity;
  517.             strcpy(pd->name,"gravity");
  518.             break;
  519.         case 4:
  520.             pd->type='f';
  521.             pd->data=&walkvel;
  522.             strcpy(pd->name,"walkvel");
  523.             break;
  524.         case 5:
  525.             pd->type='f';
  526.             pd->data=&rotvel;
  527.             strcpy(pd->name,"rotvel");
  528.             break;
  529.         case 6:
  530.             pd->type='f';
  531.             pd->data=&mousespeed;
  532.             strcpy(pd->name,"mousespeed");
  533.             break;
  534.         case 7:
  535.             pd->type=TYPE_SPOT_LIGHT;
  536.             pd->data=&spot;
  537.             strcpy(pd->name,"spot");
  538.             break;
  539.         case 8:
  540.             pd->type=TYPE_GUN;
  541.             pd->data=&g;
  542.             strcpy(pd->name,"gun");
  543.             break;
  544.         case 9:
  545.             pd->type='m';
  546.             pd->data=&p_anim[0];
  547.             strcpy(pd->name,"p_stand");
  548.             break;
  549.         case 10:
  550.             pd->type='m';
  551.             pd->data=&p_anim[1];
  552.             strcpy(pd->name,"p_run");
  553.             break;
  554.         case 11:
  555.             pd->type='m';
  556.             pd->data=&p_anim[2];
  557.             strcpy(pd->name,"p_attack");
  558.             break;
  559.         case 12:
  560.             pd->type='m';
  561.             pd->data=&w_anim[0];
  562.             strcpy(pd->name,"w_stand");
  563.             break;
  564.         case 13:
  565.             pd->type='m';
  566.             pd->data=&w_anim[1];
  567.             strcpy(pd->name,"w_run");
  568.             break;
  569.         case 14:
  570.             pd->type='m';
  571.             pd->data=&w_anim[2];
  572.             strcpy(pd->name,"w_attack");
  573.             break;
  574.         case 15:
  575.             pd->type=TYPE_SHADOW;
  576.             pd->data=&personshadow;
  577.             strcpy(pd->name,"shadow");
  578.             break;
  579.         case 16:
  580.             pd->type='p';
  581.             pd->data=&skin;
  582.             strcpy(pd->name,"skin");
  583.             break;
  584.         case 17:
  585.             pd->type='i';
  586.             pd->data=&ngib;
  587.             strcpy(pd->name,"ngib");
  588.             break;
  589.         case 18:
  590.             pd->type=TYPE_GIB;
  591.             pd->data=&gb;
  592.             strcpy(pd->name,"gibobj");
  593.             break;
  594.         case 19:
  595.             pd->type='f';
  596.             pd->data=&gibforce;
  597.             strcpy(pd->name,"gibforce");
  598.             break;
  599.         case 20:
  600.             pd->type='i';
  601.             pd->data=&zoomtime;
  602.             strcpy(pd->name,"zoomtime");
  603.             break;
  604.         case 21:
  605.             pd->type='f';
  606.             pd->data=&zoomangle1;
  607.             strcpy(pd->name,"zoomangle1");
  608.             break;
  609.         case 22:
  610.             pd->type='f';
  611.             pd->data=&zoomangle2;
  612.             strcpy(pd->name,"zoomangle2");
  613.             break;
  614.         case 23:
  615.             pd->type='f';
  616.             pd->data=&shield;
  617.             strcpy(pd->name,"shield");
  618.             break;
  619.     }
  620.     return 24;
  621. }
  622.  
  623. int person::message(vector& p,float rad,int msg,int param,void *data)
  624. {
  625.     if (msg==FLYOBJM_DAMAGE)
  626.     {
  627.         vector v=pos-p;
  628.         float len=v.length();
  629.         if (len>rad || len<SMALL)
  630.             return 0;
  631.  
  632.         flyengine->excludecollision=this;
  633.         if(flyengine->collision_test(flyengine->bsp, p, pos))
  634.         {
  635.             flyengine->excludecollision=0;
  636.             return 0;
  637.         }
  638.         flyengine->excludecollision=0;
  639.  
  640.         if (directx->mpmode!=FLYMP_CLIENT)
  641.         {
  642.             float value=*((float *)data)*(1.0f-len/rad);
  643.             jumpvec=v*((*((float *)data))/(len*100));
  644.             if (contactobj && jumpvec.z<0)
  645.                 jumpvec.z=-jumpvec.z;
  646.             jumpflag=50;
  647.             if (directx->mpmode==FLYMP_SERVER)
  648.                 mp_send_damage(param,jumpvec,value);
  649.             else flyengine->filter.x=1.0f;
  650.             curshield-=value;
  651.             if (curshield<=0)
  652.                 die(param,p,-1);
  653.         }
  654.     }
  655.     else
  656.     if (flyengine->hwlights)
  657.         if (msg==FLYOBJM_ILLUM || msg==FLYOBJM_DYNILLUM)
  658.             dynlights.add_light(p,*((vector *)data),rad);
  659.         else ;
  660.     else if (msg==FLYOBJM_ILLUM)
  661.     {
  662.         float fac=(p-pos).length()/rad;
  663.         if (fac<1.0f)
  664.             dynlight+=*((vector *)data)*(1.0f-fac);
  665.     }
  666.  
  667.     return 1;
  668. }
  669.